home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 API Bible / Windows 95 API Bible 3 Disc Set.iso / Win32 API Bible Book 3 of 3 / CHAPTE10 / INITIAL / LINE.C < prev    next >
C/C++ Source or Header  |  1996-04-28  |  18KB  |  609 lines

  1.  
  2. #include <windows.h> 
  3. #include <windowsx.h> 
  4. #include "line.h" 
  5. #include "tapi.h"
  6.  
  7. #define BUFSIZE 256
  8. #define APIHIVERSION     0x00010028    /* 1.40 */
  9. #define APILOWVERSION    0x00010000    /* 1.0 */
  10. #define EXTHIVERSION     0x00010005    /* 1.5 */
  11. #define EXTLOWVERSION    0x00000009    /* 0.9 */ 
  12. #define OWNER        0
  13. #define MONITOR      1
  14. #define MAX_CALL        3
  15. #define MAX_LINE        2
  16.  
  17.  
  18. #if defined (WIN32)
  19.     #define IS_WIN32 TRUE
  20. #else
  21.     #define IS_WIN32 FALSE
  22. #endif
  23.  
  24. #define IS_NT      IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
  25. #define IS_WIN32S  IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
  26. #define IS_WIN95   (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
  27.  
  28. HINSTANCE hInst;   // current instance
  29. HWND hWnd;         // parent window handle
  30. HWND hListWnd;     // listbox
  31. HDC  hdc;
  32. TEXTMETRIC  tm ;
  33.  
  34.  
  35. LPCTSTR lpszAppName = "lineInitialize";
  36. LPCTSTR lpszTitle   = "lineInitialize"; 
  37.  
  38.  
  39. BOOL RegisterWin95( CONST WNDCLASS* lpwc );
  40.  
  41.  
  42. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  43.                       LPTSTR lpCmdLine, int nCmdShow)
  44. {
  45.    MSG      msg;
  46.    WNDCLASS wc;
  47.  
  48.    wc.style         = CS_HREDRAW | CS_VREDRAW;
  49.    wc.lpfnWndProc   = (WNDPROC)WndProc;       
  50.    wc.cbClsExtra    = 0;                      
  51.    wc.cbWndExtra    = 0;                      
  52.    wc.hInstance     = hInstance;              
  53.    wc.hIcon         = LoadIcon (hInstance, lpszAppName); 
  54.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  55.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  56.    wc.lpszMenuName  = lpszAppName;              
  57.    wc.lpszClassName = lpszAppName;              
  58.  
  59.    if ( IS_WIN95 )
  60.    {
  61.       if ( !RegisterWin95( &wc ) )
  62.          return( FALSE );
  63.    }
  64.    else if ( !RegisterClass( &wc ) )
  65.       return( FALSE );
  66.  
  67.    hInst = hInstance; 
  68.  
  69.    hWnd = CreateWindow( lpszAppName, 
  70.                         lpszTitle,    
  71.                         WS_OVERLAPPEDWINDOW, 
  72.                         CW_USEDEFAULT, 0, 
  73.                         CW_USEDEFAULT, 0,  
  74.                         NULL,              
  75.                         NULL,              
  76.                         hInstance,         
  77.                         NULL               
  78.                       );
  79.  
  80.    if ( !hWnd ) 
  81.       return( FALSE );
  82.  
  83.    ShowWindow( hWnd, nCmdShow ); 
  84.    UpdateWindow( hWnd );         
  85.  
  86.    while( GetMessage( &msg, NULL, 0, 0) )   
  87.    {
  88.       TranslateMessage( &msg ); 
  89.       DispatchMessage( &msg );  
  90.    }
  91.  
  92.    return( msg.wParam ); 
  93. }
  94.  
  95.  
  96. BOOL RegisterWin95( CONST WNDCLASS* lpwc )
  97. {
  98.     WNDCLASSEX wcex;
  99.  
  100.    wcex.style         = lpwc->style;
  101.    wcex.lpfnWndProc   = lpwc->lpfnWndProc;
  102.    wcex.cbClsExtra    = lpwc->cbClsExtra;
  103.    wcex.cbWndExtra    = lpwc->cbWndExtra;
  104.    wcex.hInstance     = lpwc->hInstance;
  105.    wcex.hIcon         = lpwc->hIcon;
  106.    wcex.hCursor       = lpwc->hCursor;
  107.    wcex.hbrBackground = lpwc->hbrBackground;
  108.    wcex.lpszMenuName  = lpwc->lpszMenuName;
  109.    wcex.lpszClassName = lpwc->lpszClassName;
  110.  
  111.    // Added elements for Windows 95.
  112.    //...............................
  113.    wcex.cbSize = sizeof(WNDCLASSEX);
  114.    wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName, 
  115.                             IMAGE_ICON, 16, 16,
  116.                             LR_DEFAULTCOLOR );
  117.             
  118.    return RegisterClassEx( &wcex );
  119. }
  120.  
  121. #define CONFCALL    1
  122. #define CONSULT      2
  123.  
  124. enum CallState
  125. {
  126.     Idle,
  127.     Offering,
  128.     Accepted,
  129.     Dialtone,
  130.     Dialing,
  131.     Ringback,
  132.     Busy,
  133.     Special,
  134.     Connected,
  135.     Proceeding,
  136.     Conferenced,
  137.     Onholdconf,
  138.     Disconnected,
  139.     Unknown
  140. };
  141.  
  142. typedef struct tagMYINFO      // general application information
  143. {
  144.     HLINEAPP lineApp;         // instance handle TAPI gives back to us                                                                              through lineInitialize()
  145.     DWORD dwNumDevices;       // number of available devices
  146.     DWORD dwAPIVersion;       // API version the line supports
  147.      DWORD dwExtVersion;           // extended version
  148.     char szLocation[128];     // location        
  149.      char szCallingCard[128];  // calling card being used
  150.     char szAreaCode[4];       // area code       
  151.     char szCountry[128];      // calling card being used
  152. } MYINFO;
  153.  
  154. typedef struct tagLINEINFO  // information on an open line
  155. {
  156.     DWORD dwNumAddress;     // number of available addresses on the line 
  157.     HLINE hLine;            // handle to the line as returned by lineOpen 
  158.      DWORD dwLineID;         // the line ID of this line
  159.     char  szLineName[128];  // the line's name 
  160.  
  161. } MYLINEINFO;
  162.  
  163. typedef struct tagMYCALLINFO  //information on a call                     
  164. {
  165.     
  166. DWORD       eCallState;    // TAPI's line call State, set as user-defined enums
  167. DWORD      dwRequestID;   // requestID returned by async TAPI functions lineMakeCall/lineDropCall
  168. DWORD      dwAddressID;   // the originating address ID of the call being made 
  169. LPCSTR     lpszAddress;    
  170. HLINE     hLine;         // handle to the line 
  171. HCALL        hCall;         // handle to the call 
  172.    
  173. char szDialString[TAPIMAXDESTADDRESSSIZE];  //phone number being dialed
  174. char szDialStringOriginal[TAPIMAXDESTADDRESSSIZE];
  175. char szDialStringCanonical[TAPIMAXDESTADDRESSSIZE];
  176. char szCalledParty[TAPIMAXCALLEDPARTYSIZE]; // name of the party
  177. DWORD dwTranslateResults;
  178.         
  179. } MYCALLINFO;
  180.  
  181. enum CallAction     // Declare enum type CallAction (used in lineSetAppSpecific)
  182. {
  183.    HOLD,            // hold the call
  184.    TRANSFER,        // transfer the call
  185.    REDIRECT,        // redirect the call
  186.    DROP,            // drop the call
  187.    PARK             // park the call
  188. }; 
  189.  
  190. MYINFO myInfo;          //instance of MYINFO structure
  191. MYLINEINFO myLineInfo[MAX_LINE];  //instance of MYLINEINFO structure
  192. MYCALLINFO myCallInfo[MAX_CALL]; //array of MYCALLINFO strcuture
  193.  
  194. LONG lRet;        //return code
  195. char buf[BUFSIZE];    // buffer for debug message
  196.  
  197. DWORD dwLineID = 0;
  198. DWORD i;
  199. LINEEXTENSIONID        ext_id;
  200. LINEDEVCAPS            *plineDevCaps;
  201. LINEADDRESSCAPS        *plineAdddressCaps;
  202. LINEADDRESSSTATUS     *plineAddressStat;
  203. LINECALLINFO            *plineCallInfo;
  204. LINECALLSTATUS         *plineCallStatus;
  205. LINECALLLIST            *plineCallList;
  206. LINEDEVSTATUS           *plineDevStatus;
  207. LINETRANSLATECAPS       *plineTranslateCaps;
  208. LINETRANSLATEOUTPUT  *plineTranslateOutput;
  209. LINECALLPARAMS           *plineCallParams;
  210. LINEDEVSTATUS           *plineDevStatus;
  211. LINEFORWARDLIST        *plineForwardList;
  212. LINETRANSLATECAPS       *plineTranslateCaps;
  213. LINEREQMAKECALL       lineReqMakeCall;
  214. VARSTRING               *pDeviceConfig;
  215. VARSTRING               *pDeviceId;
  216. VARSTRING               *pNonDirAddress;
  217.  
  218. LPLINELOCATIONENTRY  lineLocEntry;
  219. LPLINECARDENTRY        lineCardEntry;
  220. LINECOUNTRYLIST         *plineCountryList;
  221. LPLINECOUNTRYENTRY   lineCE;
  222.  
  223. LPSTR                lpData;
  224.  
  225. HICON                hIcon = NULL;        //used in lineGetID();
  226. DWORD                dwNumRings;    //used in lineGetNumRings();
  227. HCALL                hConsultCall; //handle to consultation linePrepareAddToConference, SetupConference
  228. HCALL                hConfCall; //handle to consultation linePrepareAddToConference, SetupConference   
  229. HCALL                hParkedCall;
  230.  
  231. DWORD                dwCompletionID;  //used in lineCompleteCall()
  232.  
  233. char                szName[128];
  234. char                szNumber[128];
  235. char                szDigits[128];
  236. char                szDevConfig[128];
  237.  
  238. LONG lRet;
  239. char buf[BUFSIZE];
  240.  
  241. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  242. {
  243.    switch( uMsg )
  244.    {
  245.       case WM_COMMAND :
  246.          switch( LOWORD( wParam ) )
  247.          {
  248.             case IDM_RUN :
  249.                break;                      
  250.             
  251.             case IDM_ABOUT :
  252.             {
  253.                 DialogBox( hInst, "AboutBox", hWnd, (DLGPROC)About );
  254.                break;
  255.             }
  256.  
  257.             case IDM_EXIT :
  258.             {
  259.                for (i = 0; i < myInfo.dwNumDevices; i++)
  260.                        lineClose(myLineInfo[i].hLine);
  261.                     lineShutdown(myInfo.lineApp);
  262.                DestroyWindow( hWnd );
  263.                break;
  264.             }
  265.             }                  
  266.                  
  267.          break;
  268.  
  269.       case WM_CREATE :
  270.       {
  271.          hdc = GetDC (hWnd) ;
  272.          GetTextMetrics (hdc, &tm) ;
  273.          ReleaseDC (hWnd, hdc) ;
  274.  
  275.          hListWnd = CreateWindowEx( 0, "listbox", 
  276.                         " ",    
  277.                         WS_CHILD | WS_VISIBLE,  
  278.                         tm.tmAveCharWidth, tm.tmHeight * 3, 
  279.                         tm.tmAveCharWidth * 16 +
  280.                                    GetSystemMetrics (SM_CXVSCROLL), 
  281.                         tm.tmHeight * 5,  
  282.                         hWnd,              
  283.                         NULL,              
  284.                         hInst,         
  285.                         NULL               
  286.                         );
  287.  
  288.          
  289.          //lineInitialize
  290.             //...............................................
  291.          lRet = lineInitialize(&myInfo.lineApp, hInst, lineCallback, NULL, &myInfo.dwNumDevices);
  292.          if (lRet == 0) 
  293.          {
  294.             wsprintf (buf, "lineInitialize suceeded!");
  295.               SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
  296.            }
  297.          else 
  298.           {
  299.                wsprintf ( buf,"lineInitialize failed, err=x%lx",lRet);
  300.                SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
  301.                lineError(lRet);
  302.                break;
  303.          }                    
  304.          
  305.          //lineNegotiateAPIVersion
  306.           //...............................................
  307.          lRet = lineNegotiateAPIVersion(myInfo.lineApp, 0, APILOWVERSION, APIHIVERSION, 
  308.                                            &myInfo.dwAPIVersion, &ext_id);
  309.          if (lRet == 0)                        
  310.          {
  311.             wsprintf (buf, "lineNegotiateAPIVersion suceeded!");
  312.               SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
  313.          }
  314.          else 
  315.           {
  316.                wsprintf (buf, "lineNegotiateAPIVersion failed, err=x%lx",
  317.                            lRet);
  318.                SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
  319.                lineError(lRet);
  320.                lineShutdown (myInfo.lineApp);
  321.             break;
  322.          }
  323.  
  324.           //lineNegotiateExtVersion
  325.           //...............................................
  326.          lRet = lineNegotiateExtVersion(myInfo.lineApp, 0, myInfo.dwAPIVersion, EXTLOWVERSION, 
  327.                                            EXTHIVERSION, &myInfo.dwExtVersion);
  328.          if (lRet == 0)                        
  329.          {
  330.             wsprintf (buf, "lineNegotiateExtVersion suceeded!");
  331.             SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
  332.  
  333.          }
  334.           else 
  335.           {
  336.                wsprintf (buf, "lineNegotiateExtVersion failed, err=x%lx",
  337.                      lRet);
  338.               SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
  339.               lineError(lRet);
  340.       
  341.          }
  342.          break;
  343.       }
  344.       
  345.       case WM_SIZE:
  346.           MoveWindow(hListWnd,0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
  347.          break;
  348.  
  349.       case WM_DESTROY :
  350.               PostQuitMessage(0);
  351.               break;
  352.  
  353.       default :
  354.             return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
  355.    }
  356.  
  357.    return( 0L );
  358. }
  359.  
  360.  
  361.  
  362. /****************************************************************************
  363.     FUNCTION: lineCallback
  364.     PURPOSE:  callback function handles line events
  365. ****************************************************************************/
  366. LRESULT CALLBACK lineCallback (DWORD dwDevice, DWORD dwMsg,
  367.                                        DWORD dwCallbackInst, DWORD dwParam1,
  368.                                        DWORD dwParam2,DWORD dwParam3)
  369. {
  370.    switch (dwMsg)
  371.    {
  372.       case LINE_CALLSTATE:
  373.        {
  374.             for (i = 0; i < MAX_CALL; i++)
  375.            {
  376.                 if (dwDevice = (DWORD) myCallInfo[i].hCall) 
  377.                  switch (dwParam1)
  378.                  {
  379.                     case LINECALLSTATE_IDLE:
  380.                         myCallInfo[i].eCallState = Idle;
  381.                   break;
  382.                     
  383.                     case LINECALLSTATE_OFFERING:
  384.                         myCallInfo[i].eCallState = Offering;
  385.                          break;
  386.                     
  387.                     case LINECALLSTATE_ACCEPTED:
  388.                         myCallInfo[i].eCallState = Accepted;
  389.                         break;
  390.                     
  391.                     case LINECALLSTATE_DIALTONE:
  392.                         myCallInfo[i].eCallState = Dialtone;
  393.                   break;
  394.                     
  395.                     case LINECALLSTATE_DIALING:
  396.                         myCallInfo[i].eCallState = Dialing;
  397.                         break;
  398.                   
  399.                   case LINECALLSTATE_RINGBACK:
  400.                         myCallInfo[i].eCallState = Ringback;
  401.                         break;
  402.             
  403.                     case LINECALLSTATE_BUSY:
  404.                         myCallInfo[i].eCallState = Busy;
  405.                         break;
  406.             
  407.                     case LINECALLSTATE_SPECIALINFO:
  408.                         myCallInfo[i].eCallState = Special;
  409.                        break;
  410.             
  411.                     case LINECALLSTATE_CONNECTED:
  412.                        myCallInfo[i].eCallState = Connected;
  413.                   break;
  414.  
  415.                     case LINECALLSTATE_PROCEEDING:
  416.                         myCallInfo[i].eCallState = Proceeding;
  417.                        break;
  418.             
  419.                     case LINECALLSTATE_CONFERENCED:
  420.                         myCallInfo[i].eCallState = Conferenced;
  421.                        break;
  422.             
  423.                     case LINECALLSTATE_ONHOLDPENDCONF:
  424.                         break;
  425.                 
  426.                case LINECALLSTATE_DISCONNECTED:
  427.                         myCallInfo[i].eCallState = Disconnected;
  428.                        break;
  429.             
  430.                     case LINECALLSTATE_UNKNOWN:
  431.                         myCallInfo[i].eCallState = Unknown;
  432.                        break;
  433.        
  434.              }
  435.           }
  436.        }
  437.  
  438.        case LINE_MONITORMEDIA:
  439.            break;
  440.  
  441.        case LINE_MONITORDIGITS:
  442.           break;
  443.  
  444.          case LINE_MONITORTONE:
  445.           break;
  446.    
  447.        //error handling for functions completed asynchronously
  448.         //.....................................................
  449.        case LINE_REPLY:
  450.         {
  451.             for (i = 0; i < MAX_CALL; i++)
  452.            {
  453.                 if (dwParam1 = myCallInfo[i].dwRequestID)
  454.                {
  455.                    if (dwParam2 != 0)
  456.                    {
  457.                        lineError((LONG) dwParam2);
  458.                        break;
  459.                    }
  460.                }
  461.            }
  462.         break;
  463.         }
  464.  
  465.         case LINE_GENERATE:
  466.           break;
  467.      
  468.        case LINE_REQUEST:
  469.          break;
  470.  
  471.         case LINE_GATHERDIGITS:
  472.            break;
  473.    }
  474.  
  475.    return (TRUE);
  476.  
  477.  
  478. /****************************************************************************
  479.     FUNCTION: lineError
  480.     PURPOSE:  line error messages
  481. ****************************************************************************/
  482. void lineError (LONG lrc)
  483. {
  484.  switch (lrc) {
  485.     case LINEERR_INVALAPPHANDLE:
  486.        MessageBox (hWnd, "Invalid app handle.", "", MB_OK);
  487.        break;
  488.     case LINEERR_BADDEVICEID:
  489.        MessageBox (hWnd,"The specified line device ID is out of range.", "", 
  490.                    MB_OK);
  491.        break;
  492.     case LINEERR_INCOMPATIBLEAPIVERSION:
  493.        MessageBox (hWnd, "Incompatible API version.", "", MB_OK);
  494.        break;
  495.     
  496.     case LINEERR_ADDRESSBLOCKED:
  497.        MessageBox (hWnd, "Address was blocked.", "", MB_OK);
  498.        break;
  499.  
  500.     case LINEERR_BEARERMODEUNAVAIL:
  501.        MessageBox (hWnd, "Bearer Mode Unavailable.", "", MB_OK);
  502.        break;
  503.  
  504.     case LINEERR_CALLUNAVAIL:
  505.        MessageBox (hWnd, "Call appearances in use..", "", MB_OK);
  506.        break;
  507.  
  508.     case LINEERR_INUSE:
  509.        MessageBox (hWnd, "Line in Use.", "", MB_OK);
  510.        break;
  511.     
  512.     case LINEERR_INVALADDRESS:
  513.        MessageBox (hWnd, "Invalid Address.", "", MB_OK);
  514.        break;
  515.  
  516.     case LINEERR_INVALADDRESSID:
  517.        MessageBox (hWnd, "Invalid Address ID.", "", MB_OK);
  518.        break;
  519.  
  520.     case LINEERR_INVALCALLPARAMS:
  521.        MessageBox (hWnd, "Invalid Address ID.", "", MB_OK);
  522.        break;
  523.      
  524.     case LINEERR_INCOMPATIBLEEXTVERSION:
  525.        MessageBox (hWnd, "Incompatible extension version.","", MB_OK);
  526.        break;
  527.     case LINEERR_NOMEM:
  528.        MessageBox (hWnd, "No memory","", MB_OK);
  529.        break;
  530.     case LINEERR_NODRIVER:
  531.        MessageBox (hWnd, "No driver loaded", "", MB_OK);
  532.        break;
  533.     case LINEERR_RESOURCEUNAVAIL:
  534.        MessageBox (hWnd, "Resource overcommittment", "", MB_OK);
  535.        break;
  536.     case LINEERR_INVALPRIVSELECT:
  537.        MessageBox (hWnd, "Requested invalid priviledges", "", MB_OK);
  538.        break;
  539.     case LINEERR_INVALMEDIAMODE:
  540.        MessageBox (hWnd, "Requested invalid media mode", "", MB_OK);
  541.        break;
  542.     case LINEERR_LINEMAPPERFAILED:
  543.        MessageBox (hWnd, "Line mapper failed", "", MB_OK);
  544.        break;
  545.     case LINEERR_INVALPOINTER:
  546.        MessageBox (hWnd, "The specified pointer parameter is invalid.",
  547.                    "", MB_OK);
  548.        break;
  549.     case LINEERR_OPERATIONFAILED:
  550.        MessageBox (hWnd, "Operation failed.", "", MB_OK);
  551.        break;
  552.     case LINEERR_INVALLINEHANDLE:
  553.        MessageBox (hWnd, "Invalid line handle", "", MB_OK);
  554.        break;
  555.     case LINEERR_INVALCALLHANDLE:
  556.        MessageBox (hWnd, "Invalid call handle", "", MB_OK);
  557.        break;
  558.     case LINEERR_INVALCALLSELECT:
  559.        MessageBox (hWnd, "Invalid call selection", "", MB_OK);
  560.        break;
  561.     case LINEERR_NODEVICE:
  562.        MessageBox (hWnd, "No associated device for given class",
  563.                    "", MB_OK);
  564.        break;
  565.     case LINEERR_OPERATIONUNAVAIL:
  566.        MessageBox (hWnd, "The operation is unavailable",
  567.                    "", MB_OK);
  568.        break;
  569.     case LINEERR_INVALPARAM:
  570.         MessageBox(hWnd, "Invalid Paramater", "", MB_OK);
  571.        break; 
  572.  
  573.     case LINEERR_TARGETNOTFOUND:
  574.         MessageBox(hWnd, "Target Not Found", "", MB_OK);
  575.        break; 
  576.  
  577.    case LINEERR_NOREQUEST:
  578.       MessageBox(hWnd, "No outstanding Assisted Telephony requests.", "", MB_OK);
  579.        break; 
  580.    }
  581. }
  582.  
  583. LRESULT CALLBACK About( HWND hDlg,           
  584.                         UINT message,        
  585.                         WPARAM wParam,       
  586.                         LPARAM lParam)
  587. {
  588.    switch (message) 
  589.    {
  590.        case WM_INITDIALOG: 
  591.                return (TRUE);
  592.  
  593.        case WM_COMMAND:                              
  594.                if (   LOWORD(wParam) == IDOK         
  595.                    || LOWORD(wParam) == IDCANCEL)    
  596.                {
  597.                        EndDialog(hDlg, TRUE);        
  598.                        return (TRUE);
  599.                }
  600.                break;
  601.    }
  602.  
  603.    return (FALSE); 
  604. }
  605.  
  606.  
  607.  
  608.